package com.foreveross.proxyip.local;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.foreveross.crawl.common.InstanceFactory;
import com.foreveross.crawl.common.cfg.PropertyUtils;
import com.foreveross.crawl.common.cfg.system.EnginePropertiesLoader;
import com.foreveross.proxyip.IProxyIpProvider;
import com.foreveross.proxyip.ProxyIpModel;
import com.foreveross.proxyip.remote.RmiProxyIpProvider;

/**
 * 远程代理ip池
 * <p>一个带有实例id代理ip池，默认实例ID为RmiChannelInstance<br/>,第一次取IP时从远程统一代理Ip接口取得一批代理IP放入到代理IP池中
 * <p>一个IP可能无限重复使用，只要IP可用
 * <p>一个节点上只有一个渠道池,池内IP供所有渠道使用
 * @author xiangsf 2014-09-23
 *
 */
public class ProxyIpRmiChannelPool extends ProxyIpSimplePool{
	
	public Logger logger = LoggerFactory.getLogger(ProxyIpRmiChannelPool.class);
	public final static String DEFAULT_PROXY_POOL_INSTANCEID = "RmiChannelInstance";
	private IProxyIpProvider proxyIPRMIService;
	private List<String> useProxyIpChannels = null;
	public ProxyIpRmiChannelPool(String poolInstanceId){
		super(poolInstanceId);
		//注入远程的代理Ip服务接口
		proxyIPRMIService = InstanceFactory.getInstance(RmiProxyIpProvider.class);
		useProxyIpChannels =  PropertyUtils.getListPropertys("engine.channel.id.proxyip.contains",
						EnginePropertiesLoader.FILE_NAME, ",");
	}

	public synchronized void swapProxyIp(ProxyIpModel model){
		if(model != null){
			logger.info(String.format("代理IP[%s]非常好用,返回到池中继续使用.",model.getProxyIp()));
			this.addIps(model);
		}
	}
	private ProxyIpModel getAbleProxyIp(String channelId){
		ProxyIpModel m = null;
		List<ProxyIpModel> tempList = proxyIps;
		for(ProxyIpModel ip : tempList){
			if(ip.isExcludeChannel(channelId)) continue;
			m = ip;
			break;
		}
		tempList = null;
		if(m == null){//下载一批
			while(tempList == null || tempList.size()<=0){
				try {
					Thread.sleep(3000l);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				tempList = proxyIPRMIService.provideProxyIps(channelId);
			}
			this.addIps(tempList);
			return getAbleProxyIp(channelId);//再递归获取，直到能取到Ip出去
		}
		tempList = null;
		return m;
	}
	/**
	 * 获得指定渠道标识为可用的IP
	 * @param channelId
	 * @return
	 */
	public synchronized ProxyIpModel getProxyIp(String channelId){
		logger.info("simple pool size:"+ proxyIps.size());
		//有则直接获得对象，并称除
		if(proxyIps != null && !proxyIps.isEmpty()){
			//如果超时，则拿下一个
			ProxyIpModel m = this.getAbleProxyIp(channelId);
		
			logger.info("simple pool size:"+ proxyIps.size());
			proxyIps.remove(m); //从队列中移走
			//累计次数
			m.countUseCount();
			m.setHasRecycle(false);
			return m;
		}else{
			this.addIps(proxyIPRMIService.provideProxyIps(channelId));
			return getProxyIp(channelId);
		}
	}
	
	public synchronized boolean remove(ProxyIpModel model){
		if(model != null){ //如果所有使用代理IP的渠道都不可用了，则从池中丢弃
			logger.info(String.format("代理IP[%s]完全不可用验证,从池中丢弃.",model.getProxyIp()));
			return model.getChannelStatusMapKeys().containsAll(useProxyIpChannels);
		}
		return false;
	}
}
